#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/joystick.h>

#include "driver_Xbox_Joystick.h"

 
 /* 获得手柄设备输入流 */
int xbox_open(char *file_name)
{
    int xbox_fd;
 
    xbox_fd = open(file_name, O_RDONLY);
    if (xbox_fd < 0)
    {
        perror("open");
        return -1;
    }
 
    return xbox_fd;
}
 
 /* 读取手柄数据 */
int xbox_map_read(int xbox_fd, xbox_map_t *map)
{
    int len, type, number, value;
    struct js_event js;
 
    len = read(xbox_fd, &js, sizeof(struct js_event));
    if (len < 0)
    {
        perror("read");
        return -1;
    }
 
    type = js.type;
    number = js.number;
    value = js.value;
 
    map->time = js.time;
 
    if (type == JS_EVENT_BUTTON)
    {
        switch (number)
        {
            case XBOX_BUTTON_A:
                map->a = value;
                break;
 
            case XBOX_BUTTON_B:
                map->b = value;
                break;
 
            case XBOX_BUTTON_X:
                map->x = value;
                break;
 
            case XBOX_BUTTON_Y:
                map->y = value;
                break;
 
            case XBOX_BUTTON_LB:
                map->lb = value;
                break;
 
            case XBOX_BUTTON_RB:
                map->rb = value;
                break;
 
            case XBOX_BUTTON_SELECT:
                map->select = value;
                break;
 
            case XBOX_BUTTON_START:
                map->start = value;
                break;
 
            case XBOX_BUTTON_HOME:
                map->home = value;
                break;
 
            case XBOX_BUTTON_LO:
                map->lo = value;
                break;
 
            case XBOX_BUTTON_RO:
                map->ro = value;
                break;
 
            default:
                break;
        }
    }
    else if (type == JS_EVENT_AXIS)
    {
        switch(number)
        {
            case XBOX_AXIS_LX:
                map->lx = value;
                break;
 
            case XBOX_AXIS_LY:
                map->ly = value;
                break;
 
            case XBOX_AXIS_RX:
                map->rx = value;
                break;
 
            case XBOX_AXIS_RY:
                map->ry = value;
                break;
 
            case XBOX_AXIS_LT:
                map->lt = value;
                break;
 
            case XBOX_AXIS_RT:
                map->rt = value;
                break;
 
            case XBOX_AXIS_XX:
                map->xx = value;
                break;
 
            case XBOX_AXIS_YY:
                map->yy = value;
                break;
 
            default:
                break;
        }
    }
    else
    {
        /* 若出错 */
    }
 
    return len;
}

/* 关闭手柄设备输入流 */ 
void xbox_close(int xbox_fd)
{
    close(xbox_fd);
    return;
}
 
 
 
int test(void)
{
    int xbox_fd ;
    xbox_map_t map;
    int len, type;
    int axis_value, button_value;
    int number_of_axis, number_of_buttons ;
 
    memset(&map, 0, sizeof(xbox_map_t));
 
    xbox_fd = xbox_open((char*)("/dev/input/js0"));
    if(xbox_fd < 0)
    {
        return -1;
    }
 
    while(1)
    {
        len = xbox_map_read(xbox_fd, &map);
        if (len < 0)
        {
            usleep(10*1000);
            continue;
        }
 
        printf("\rTime:%8d A:%d B:%d X:%d Y:%d LB:%d RB:%d select:%d start:%d lo:%d ro:%d XX:%-6d YY:%-6d LX:%-6d LY:%-6d RX:%-6d RY:%-6d LT:%-6d RT:%-6d",
                map.time, map.a, map.b, map.x, map.y, map.lb, map.rb, map.select, map.start, map.lo, map.ro,
                map.xx, map.yy, map.lx, map.ly, map.rx, map.ry, map.lt, map.rt);
        fflush(stdout);
    }
 
    xbox_close(xbox_fd);
    return 0;
}

JoyStickDriver::JoyStickDriver(){
    JoyStickInit();
}

JoyStickDriver::~JoyStickDriver(){
    JoyStickClose();
}

int JoyStickDriver::JoyStickInit(){
    JoystickFd = xbox_open((char*)("/dev/input/js0"));
    if(JoystickFd < 0) {
        return -1;
    }
    return 0;
}

int JoyStickDriver::JoyStickRead(xbox_map_t *pMap){
    return xbox_map_read(JoystickFd, pMap);
}

int JoyStickDriver::JoyStickRead(void){
    return xbox_map_read(JoystickFd, &joystickData);
}

int JoyStickDriver::JoyStickClose(){
    xbox_close(JoystickFd);
    return 0;
}

